package com.natalia.file.controller;

import com.google.gson.Gson;
import com.natalia.file.entity.*;
import com.natalia.file.service.FileService;
import com.natalia.file.struct.UploadStructBasic;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.core.io.InputStreamSource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * @Author yang
 **/
@Slf4j
@RestController
@Validated
@Api(tags = "文件服务接口")
@RequestMapping("/files")
@RequiredArgsConstructor
public class FileController {

    private  final FileService fileService;

    /**
     * 上传文件
     */
    @Operation(summary = "上传文件")
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public UploadResult download(@RequestPart("file") MultipartFile file){
        try {
            UploadInfo uploadInfo = new UploadInfo();
            uploadInfo.setFileSize(file.getSize());
            uploadInfo.setContent(file.getBytes());
            uploadInfo.setFileName(file.getOriginalFilename());
            return fileService.upload(uploadInfo);
        } catch (Exception e) {
            log.error("upload file error{}:",ExceptionUtils.getStackTrace(e));
            return null;
        }
    }

    /**
     * 下载文件
     * @param
     */
    @Operation(summary = "下载文件")
    @GetMapping("/download")
    public ResponseEntity<InputStreamSource> download(
            @Parameter(description = "文件的唯一标识符", required = true) @RequestParam("fileId") String fileId){
        WebRequest request = (WebRequest) RequestContextHolder.getRequestAttributes();
        return fileService.download(fileId,request);
    }


    /**
     * 分片上传初始化
     * @param multipartInit 分片上传请求
     * @return 初始化结果，主要是上传的ID
     */
    @Operation(summary = "分片上传初始化")
    @PostMapping("/multipartInit")
    public String createMultipartUpload(@RequestBody MultipartInit multipartInit) {
        MultipartUploadInfo init = fileService.createMultipartInit(multipartInit);
        return new Gson().toJson(init);
    }

    /**
     * 上传分片
     */
    @Operation(summary = "上传分片")
    @PostMapping("/multipart/upload")
    public String uploadPart(UploadPartRequest request) {
        UploadPartInfo partInfo = UploadStructBasic.INSTANCES.uploadPartReqToPartInfo(request);
        MultipartUploadInfo uploadInfo = fileService.uploadPart(partInfo);
        return new Gson().toJson(uploadInfo);
    }

    /**
     * 查询分片信息
     */
    @Operation(summary = "查询分片信息")
    @PostMapping("/multipart/listParts")
    public String listParts(@RequestBody ListPartsRequest request) {
        MultipartUploadCreate create = UploadStructBasic.INSTANCES.listPartsReqToMultipartUploadCreat(request);
        List<ShardUploadInfo> shardUploadInfos = fileService.listParts(create);
        return new Gson().toJson(shardUploadInfos);
    }

    /**
     * 合并分片
     * @param request 合并请求
     * @return
     */
    @Operation(summary = "合并分片")
    @PostMapping("/multipart/complete")
    public String completeMultipart(@RequestBody CompleteMultipartRequest request) {
        CompleteMultipart multipart = UploadStructBasic.INSTANCES.completeMultipartReqToComplete(request);
        CompleteUploadInfo completeUploadInfo = fileService.completeMultipart(multipart);
        return new Gson().toJson(completeUploadInfo);
    }

}
